<template>
  <BaseDialog :visible="visible" title="设备位置标记" width="1200px" :footer-type="'custom'" @close="handleClose"
    @update:visible="$emit('update:visible', $event)">
    <div class="camera-location-dialog">
      <div class="dialog-content">
        <!-- 左侧表单 -->
        <div class="form-section">
          <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px" class="location-form">
            <el-form-item label="摄像机名称" prop="name">
              <el-input v-model="formData.name" disabled />
            </el-form-item>

            <el-form-item label="摄像机ID" prop="id">
              <el-input v-model="formData.id" disabled />
            </el-form-item>
            <el-form-item label="所属流媒体" prop="nvrName">
              <el-input v-model="formData.nvrName" disabled />
            </el-form-item>

            <el-form-item label="经度" prop="longitude">
              <el-input v-model="formData.longitude" placeholder="请输入经度" @input="handleLongitudeChange" />
            </el-form-item>

            <el-form-item label="纬度" prop="latitude">
              <el-input v-model="formData.latitude" placeholder="请输入纬度" @input="handleLatitudeChange" />
            </el-form-item>

            <el-form-item>
              <el-button type="warning" @click="handleClearMarker"
                :disabled="!formData.longitude && !formData.latitude">
                清空标记
              </el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 右侧地图 -->
        <div class="map-section">
          <div id="camera-location-map" class="location-map"></div>
        </div>
      </div>
    </div>

    <template #footer>
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleSave" :loading="saving">
        保存
      </el-button>
    </template>
  </BaseDialog>
</template>

<script setup lang="ts">
import { ref, reactive, watch, nextTick, onUnmounted } from 'vue'
import BaseDialog from '@/components/BaseDialog.vue'
import type { Device, MapDeviceMark, StreamServer } from '@/types'
import { markDeviceOnMap } from '@/api/device'
import { $getAllServer } from '@/api/nvr'
import * as Cesium from 'cesium'
import { success, error } from '@/utils/toast'
import { createAmapProvider, createOSMProvider } from '@/config/mapProviders'
// Props
interface Props {
  visible: boolean
  cameraData: Device | null
}

const props = defineProps<Props>()

// Emits
const emit = defineEmits<{
  'update:visible': [value: boolean]
  'close': []
  'save': [data: { id: number; longitude: string; latitude: string }]
}>()

// 响应式数据
const formRef = ref()
const saving = ref(false)
const mapInstance = ref<any>(null)
const marker = ref<any>(null)

// 表单数据
const formData = reactive({
  id: '',
  name: '',
  nvrName: '',
  longitude: '',
  latitude: ''
})

// 表单验证规则
const formRules = {
  longitude: [
    { required: true, message: '请输入经度', trigger: 'blur' },
    { pattern: /^-?(\d{1,3}(\.\d+)?)$/, message: '请输入有效的经度', trigger: 'blur' }
  ],
  latitude: [
    { required: true, message: '请输入纬度', trigger: 'blur' },
    { pattern: /^-?(\d{1,2}(\.\d+)?)$/, message: '请输入有效的纬度', trigger: 'blur' }
  ]
}

// 默认坐标（天津）
const DEFAULT_LONGITUDE = 118.105622
const DEFAULT_LATITUDE = 39.223579

const initServerData = async () => {
  const res = await $getAllServer()
  res.data.forEach((item: StreamServer) => {
    if (item.id === props.cameraData?.nvrId) {
      formData.nvrName = item.name || ''
    }
  })
}


// 监听弹框显示状态
watch(() => props.visible, (newVal) => {
  if (newVal) {
    initFormData()
    initServerData()
    nextTick(() => {
      initMap()
    })
  }
})


// 监听摄像机数据变化
watch(() => props.cameraData, () => {
  if (props.visible) {
    initFormData()
  }
})


// 初始化表单数据
const initFormData = async () => {
  if (props.cameraData) {
    formData.id = props.cameraData.id.toString()
    formData.name = props.cameraData.name
    formData.longitude = props.cameraData.longitude || ''
    formData.latitude = props.cameraData.latitude || ''
  }
}

// 初始化地图
const initMap = () => {
  try {
    console.log('开始初始化Cesium地图...')

    // 销毁旧地图实例
    if (mapInstance.value) {
      mapInstance.value.destroy()
    }

    // 设置Cesium Token
    const token = import.meta.env.VITE_CESIUM_ION_TOKEN
    console.log('Cesium Token已设置:', token ? '已配置' : '未配置')

    // 创建地图实例
    mapInstance.value = new Cesium.Viewer('camera-location-map', {
      baseLayerPicker: false,
      geocoder: false,
      homeButton: false,
      sceneModePicker: false,
      navigationHelpButton: false,
      animation: false,
      timeline: false,
      fullscreenButton: false,
      vrButton: false,
      scene3DOnly: false,
      shouldAnimate: false
    })

    // 设置为2D模式以获得真正的垂直视角
    mapInstance.value.scene.mode = Cesium.SceneMode.SCENE2D

    // 移除默认的卫星地图，添加高德地图服务
    mapInstance.value.imageryLayers.removeAll()
    
    // 优先使用高德地图
    try {
      const amapProvider = createAmapProvider()
      mapInstance.value.imageryLayers.addImageryProvider(amapProvider)
      console.log('已加载高德地图服务')
    } catch (error) {
      console.warn('高德地图加载失败，尝试OpenStreetMap:', error)
      
      // 备用方案：使用OpenStreetMap
      try {
        const osmProvider = createOSMProvider()
        mapInstance.value.imageryLayers.addImageryProvider(osmProvider)
        console.log('已加载OpenStreetMap服务')
      } catch (osmError) {
        console.error('OpenStreetMap也加载失败:', osmError)
      }
    }

    // 设置初始视角 - 2D模式下直接设置相机位置
    if (formData.longitude && formData.latitude) {
      mapInstance.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(parseFloat(formData.longitude), parseFloat(formData.latitude), 1000)
      })
    } else {
      mapInstance.value.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(DEFAULT_LONGITUDE, DEFAULT_LATITUDE, 2000)
      })
    }

    // 如果已有坐标，则添加标记
    if (formData.longitude && formData.latitude) {
      const lng = parseFloat(formData.longitude)
      const lat = parseFloat(formData.latitude)
      if (!isNaN(lng) && !isNaN(lat)) {
        addMarker(lng, lat)
      }
    }

    // 添加地图点击事件
    mapInstance.value.cesiumWidget.screenSpaceEventHandler.setInputAction(handleMapClick, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    console.log('Cesium地图初始化成功')
  } catch (err) {
    console.error('Cesium地图初始化失败:', err)
    error('地图服务加载失败，请刷新页面重试')
  }
}

// 添加标记
const addMarker = (lng: number, lat: number) => {
  // 清除旧标记
  if (marker.value) {
    mapInstance.value.entities.remove(marker.value)
  }

  // 创建新标记 - 2D模式下使用不同的设置
  marker.value = mapInstance.value.entities.add({
    position: Cesium.Cartesian3.fromDegrees(lng, lat),
    billboard: {
      image: 'data:image/svg+xml;base64,' + btoa(`
        <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
          <circle cx="16" cy="16" r="12" fill="#ff4444" stroke="#ffffff" stroke-width="2"/>
          <circle cx="16" cy="16" r="6" fill="#ffffff"/>
        </svg>
      `),
      scale: 1.0,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      heightReference: Cesium.HeightReference.NONE
    },
    label: {
      text: '设备位置',
      font: '12pt sans-serif',
      pixelOffset: new Cesium.Cartesian2(0, -40),
      fillColor: Cesium.Color.WHITE,
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 2,
      style: Cesium.LabelStyle.FILL_AND_OUTLINE,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      heightReference: Cesium.HeightReference.NONE
    }
  })
}

// 处理地图点击
const handleMapClick = (event: any) => {
  const pickedPosition = mapInstance.value.camera.pickEllipsoid(event.position, mapInstance.value.scene.globe.ellipsoid)
  if (pickedPosition) {
    const cartographic = Cesium.Cartographic.fromCartesian(pickedPosition)
    const lng = Cesium.Math.toDegrees(cartographic.longitude)
    const lat = Cesium.Math.toDegrees(cartographic.latitude)

    formData.longitude = lng.toFixed(6)
    formData.latitude = lat.toFixed(6)
    addMarker(lng, lat)
  }
}

// 处理经度变化
const handleLongitudeChange = () => {
  if (formData.longitude && formData.latitude) {
    const lng = parseFloat(formData.longitude)
    const lat = parseFloat(formData.latitude)
    if (!isNaN(lng) && !isNaN(lat)) {
      const position = Cesium.Cartesian3.fromDegrees(lng, lat, 1000)
      mapInstance.value?.camera.setView({
        destination: position
      })
      addMarker(lng, lat)
    }
  }
}

// 处理纬度变化
const handleLatitudeChange = () => {
  if (formData.longitude && formData.latitude) {
    const lng = parseFloat(formData.longitude)
    const lat = parseFloat(formData.latitude)
    if (!isNaN(lng) && !isNaN(lat)) {
      const position = Cesium.Cartesian3.fromDegrees(lng, lat, 1000)
      mapInstance.value?.camera.setView({
        destination: position
      })
      addMarker(lng, lat)
    }
  }
}

// 清空标记
const handleClearMarker = () => {
  // 清空表单数据
  formData.longitude = ''
  formData.latitude = ''

  // 清除地图标记
  if (marker.value) {
    mapInstance.value?.entities.remove(marker.value)
    marker.value = null
  }

  // 恢复到初始状态 - 如果有设备坐标则定位到设备位置，否则定位到默认位置
  const initialPosition = props.cameraData?.longitude && props.cameraData?.latitude
    ? Cesium.Cartesian3.fromDegrees(parseFloat(props.cameraData.longitude), parseFloat(props.cameraData.latitude), 1000)
    : Cesium.Cartesian3.fromDegrees(DEFAULT_LONGITUDE, DEFAULT_LATITUDE, 2000)

  mapInstance.value?.camera.setView({
    destination: initialPosition
  })
}

// 保存
const handleSave = async () => {
  try {
    // 如果经纬度为空，不需要验证表单
    if (formData.longitude && formData.latitude) {
      const valid = await formRef.value?.validate()
      if (!valid) return
    }

    saving.value = true

    // 调用API保存位置信息
    const markData: MapDeviceMark = {
      devId: parseInt(formData.id),
      longitude: formData.longitude,
      latitude: formData.latitude,
      cancelSet: !formData.longitude || !formData.latitude // 如果经纬度为空，则设置为清空标记
    }

    await markDeviceOnMap(markData)

    // 发送保存事件
    emit('save', {
      id: parseInt(formData.id),
      longitude: formData.longitude,
      latitude: formData.latitude
    })

    const message = formData.longitude && formData.latitude ? '位置标记保存成功' : '标记已清空'
    success(message)
    handleClose()
  } catch (err) {
    console.error('保存失败:', err)
    error('保存失败，请重试')
  } finally {
    saving.value = false
  }
}

// 关闭
const handleClose = () => {
  emit('close')
  emit('update:visible', false)
}

// 组件卸载时清理地图
onUnmounted(() => {
  if (mapInstance.value) {
    mapInstance.value.destroy()
  }
})
</script>

<style scoped lang="scss">
.camera-location-dialog {
  .dialog-content {
    display: flex;
    height: 600px;
    gap: 20px;
  }

  .form-section {
    width: 400px;
    flex-shrink: 0;
    padding: 20px;
    border-right: 1px solid #e5e7eb;

    .location-form {
      .el-form-item {
        margin-bottom: 20px;
      }
    }
  }

  .map-section {
    flex: 1;
    padding: 20px;

    .location-map {
      width: 100%;
      height: 100%;
      border: 1px solid #e5e7eb;
      border-radius: 4px;
    }
  }
}

// 响应式设计
@media (max-width: 1400px) {
  .camera-location-dialog {
    .dialog-content {
      flex-direction: column;
      height: auto;
    }

    .form-section {
      width: 100%;
      border-right: none;
      border-bottom: 1px solid #e5e7eb;
    }

    .map-section {
      .location-map {
        height: 400px;
      }
    }
  }
}
</style>
